from typing import ClassVar

from .bank import Account, Debt, Mortgage
from .property import Property
from .utilities import Sequence


class Wealth:
    
    _wealth_seq: 'ClassVar[Sequence[Wealth]]' = Sequence()
    
    def __init__(self, cash: int, debt: int, interest_rate: float) -> None:
        self.account = Account(cash)
        self.debt = Debt(debt, interest_rate)
        self.properties: Sequence[Property] = Sequence()
        self.mortgages: Sequence[Mortgage] = Sequence()
        self.id = Wealth._wealth_seq.push(self)
    
    def update(self) -> None:
        self.debt.update()
        
        for id in tuple(self.mortgages.dict.keys()):
            self.mortgages.dict[id].update()
            if self.mortgages.dict[id].removable:
                self.mortgages.dict[id].onremove()
                del self.mortgages.dict[id] 
                
        for id in tuple(self.properties.dict.keys()):
            if self.properties.dict[id].removable():
                self.properties.dict[id].onremove()
                del self.properties.dict[id]
    
    def borrow(self, amount: int):
        self.account.increase(amount, "Borrowing")
        self.debt.decrease(amount, "Borrowing")
    
    def payback(self, amount: int) -> bool:
        if self.account.balance >= amount and self.debt.balance <= -amount:
            self.account.decrease(amount, "Paying back")
            self.debt.increase(amount, "Paying back")
            return True
        else:
            return False
    
    def mortgage(self, id: int, rate: float = 0.0, life: int = 0) -> int:
        if self.properties.exist(id) and (p := self.properties.get(id)).mortgagable():
            self.account.increase(p.value, "Mortgaged")
            return self.mortgages.push(Mortgage(p, rate, life))
        else:
            return -1
    
    def dismortgage(self, id: int) -> bool:
        if self.mortgages.exist(id) and self.account.balance + (m := self.mortgages.get(id)).balance >= 0:
            self.account.decrease(-m.balance, "Mortgage paid back")
            m.payback()
            return True
        else:
            return False
        
    
    def __repr__(self) -> str:
        return super().__repr__().replace("object", f"""\
object #{self.id} [
account={self.account}
debt={self.debt}
properties={self.properties}
mortgages={self.mortgages}
]""")